package ch.usi.inf.pf2.editor;

/**
 * @author Ebrisa Savina Mastrodicasa
 */


import java.util.Stack;



/**
 * UndoRedoStack is useful to allow the users to undo and redo
 * their actions. This class is necessary to recover from hypothetical
 * errors during the compilation of the spreadsheet.
 */

public class UndoRedoStack {
	
	private Stack<Action> actionsForUndoCalling;
	private Stack<Action> actionsForRedoCalling;
	private Action lastAction;
	
	
	/**
	 * Crate the UndoRedoStack.
	 */
	public UndoRedoStack()
	{
		actionsForUndoCalling = new Stack<Action>();
		actionsForRedoCalling = new Stack<Action>();
		lastAction = new NullAction();
	}
	
	
	/**
	 * Undo the last action done.
	 * @return The last action done.
	 */
	public Action undo()
	{
		if(actionsForUndoCalling.empty())
		{
			return new NullAction();
		} else {
			Action actionUndone = actionsForUndoCalling.pop();
			addActionToRedoStack(actionUndone);
			return actionUndone;
		}
	}
	
	
	/**
	 * Add an action to the stack of the
	 * possible actions to be undone.
	 * @param actionToRedo The next action that can be undone.
	 */
	public void addActionToUndoStack(Action actionToUndo)
	{
		if(actionToUndo instanceof Copy || actionToUndo instanceof Cut ||
			   actionToUndo instanceof MultipleCopy || actionToUndo instanceof MultipleCut)
		{
			lastAction = actionToUndo; System.out.println("added");
		}
		actionsForUndoCalling.push(actionToUndo);
	}
	
	
	
	/**
	 * Redo the last action done.
	 * @return The action the user wants to redo.
	 */
	public Action redo()
	{
		if(actionsForRedoCalling.empty())
		{
			return new NullAction();
		} else {
			Action actionRedone = actionsForRedoCalling.pop();
			addActionToUndoStack(actionRedone);
			return actionRedone;
		}
	}
	
	
	
	/**
	 * Add an action to the stack of the
	 * possible actions to be redone.
	 * @param actionToRedo The next action that can be redone.
	 */
	public void addActionToRedoStack(Action actionToRedo)
	{
		actionsForRedoCalling.push(actionToRedo);
	}
	
	
	/**
	 * @return The last action executed.
	 */
	public Action getLastAction()
	{
		return lastAction;
	}
	
	
	/**
	 * Allow to set the lastAction to the desired one.
	 */
	public void setLastAction(Action lastAction) 
	{
		this.lastAction = lastAction;
	}
	
	
	/**
	 * @return The actions available for the undo.
	 */
	public Stack<Action> getActionsForUndoCalling()
	{
		return actionsForUndoCalling;
	}
	
	
	/**
	 * @return The actions available for the redo.
	 */
	public Stack<Action> getActionsForRedoCalling()
	{
		return actionsForRedoCalling;
	}
}
